package cn.itcast.order;

import java.util.*;
import java.util.stream.*;

public class StreamApiDemo {
    public static void main(String[] args) {
        // 1. 创建Stream的多种方式
        System.out.println("=== 创建Stream的多种方式 ===");

        // 从集合创建
        List<String> list = Arrays.asList("Java", "Python", "C++", "JavaScript", "Go", "Ruby", "Java");
        Stream<String> streamFromList = list.stream();
        System.out.println("从List创建的Stream: ");
        streamFromList.forEach(System.out::println);


        // 从数组创建
        int[] intArray = {1, 2, 3, 4, 5};
        IntStream streamFromArray = Arrays.stream(intArray);
        System.out.println("\n从数组创建的Stream: ");
        streamFromArray.forEach(System.out::println);

        // 使用Stream.of直接创建
        Stream<String> directStream = Stream.of("Apple", "Banana", "Orange");
        System.out.println("\n直接创建的Stream: ");
        directStream.forEach(System.out::println);

        // 2. 中间操作示例
        System.out.println("\n=== 中间操作示例 ===");

        // 过滤和去重
        System.out.println("过滤长度>3且去重后的结果: ");
        list.stream()
                .filter(s -> s.length() > 3)
                .distinct()
                .forEach(System.out::println);

        // 映射转换
        System.out.println("\n转换为大写后的结果: ");
        list.stream()
                .map(String::toUpperCase)
                .forEach(System.out::println);

        // 排序
        System.out.println("\n自然排序后的结果: ");
        list.stream()
                .sorted()
                .forEach(System.out::println);

        System.out.println("\n按长度排序后的结果: ");
        list.stream()
                .sorted(Comparator.comparingInt(String::length))
                .forEach(System.out::println);

        // 3. 终端操作示例
        System.out.println("\n=== 终端操作示例 ===");

        // 统计数量
        long count = list.size();
        System.out.println("元素总数: " + count);

        // 匹配检查
        boolean anyMatch = list.stream().anyMatch(s -> s.startsWith("J"));
        System.out.println("是否有元素以J开头: " + anyMatch);

        boolean allMatch = list.stream().allMatch(s -> s.length() > 2);
        System.out.println("是否所有元素长度>2: " + allMatch);

        // 查找元素
        Optional<String> first = list.stream().findFirst();
        System.out.println("第一个元素: " + first.orElse("空"));

        // 归约操作
        Optional<String> concat = list.stream().reduce((s1, s2) -> s1 + "," + s2);
        System.out.println("拼接后的字符串: " + concat.orElse("空"));

        // 收集操作
        List<String> filteredList = list.stream()
                .filter(s -> s.length() > 3)
                .collect(Collectors.toList());
        System.out.println("\n过滤后的List: " + filteredList);

        Set<String> distinctSet = new HashSet<>(list);
        System.out.println("去重后的Set: " + distinctSet);

        String joinedString = String.join(", ", list);
        System.out.println("连接后的字符串: " + joinedString);

        // 4. 并行流示例
        System.out.println("\n=== 并行流示例 ===");
        list.parallelStream()
                .filter(s -> s.length() > 3)
                .forEach(s -> System.out.println(Thread.currentThread().getName() + ": " + s));

        // 5. 集合运算示例
        System.out.println("\n=== 集合运算示例 ===");
        List<String> list1 = Arrays.asList("A", "B", "C", "D");
        List<String> list2 = Arrays.asList("C", "D", "E", "F");

        // 并集
        List<String> union = Stream.concat(list1.stream(), list2.stream())
                .distinct()
                .collect(Collectors.toList());
        System.out.println("并集: " + union);

        // 交集
        List<String> intersection = list1.stream()
                .filter(list2::contains)
                .collect(Collectors.toList());
        System.out.println("交集: " + intersection);

        // 差集(list1 - list2)
        List<String> difference = list1.stream()
                .filter(e -> !list2.contains(e))
                .collect(Collectors.toList());
        System.out.println("差集(list1-list2): " + difference);

        // 6. 其他实用操作
        System.out.println("\n=== 其他实用操作 ===");

        // 分组
        Map<Integer, List<String>> groupByLength = list.stream()
                .collect(Collectors.groupingBy(String::length));
        System.out.println("按长度分组: " + groupByLength);

        // 分区
        Map<Boolean, List<String>> partitionByLength = list.stream()
                .collect(Collectors.partitioningBy(s -> s.length() > 3));
        System.out.println("按长度>3分区: " + partitionByLength);

        // 统计
        IntSummaryStatistics stats = list.stream()
                .mapToInt(String::length)
                .summaryStatistics();
        System.out.println("长度统计: 平均=" + stats.getAverage() +
                ", 最大=" + stats.getMax() +
                ", 最小=" + stats.getMin() +
                ", 总数=" + stats.getSum());
    }
}
